home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / OS Utilities / Feature Teller 1.0 / Feature Teller.π < prev    next >
Encoding:
Text File  |  1991-09-10  |  17.1 KB  |  727 lines  |  [TEXT/PJMM]

  1. {* ----------------------------------------------------------------------------     *}
  2. {*                                                                                                       *}
  3. {*        Apple Macintosh Developer Techincal Support                                               *}
  4. {*                                                                                                       *}
  5. {*       Feature Teller                                                                               *}
  6. {*                                                                                                       *}
  7. {*        Feature Teller.π        -     Think Pascal 3.0 Source Code                                *}
  8. {*                                                                                                       *}
  9. {*        Copyright ©  Apple Computer,  Inc.  1991                                                *}
  10. {*        All rights reserved.                                                                           *}
  11. {*                                                                                                       *}
  12. {*        Written by Jennifer Minge                                                                *}
  13. {*                                                                                                       *}
  14. {*        Versions:                                                                                    *}
  15. {*                        1.00                09/91                                                    *}
  16. {*                                                                                                       *}
  17. {*        Components:                                                                                *}
  18. {*                        Feature Teller.π                    Sept.   5,  1991                        *}
  19. {*                        Feature Teller                    Sept.   5,  1991                        *}
  20. {*                        Feature Teller.rsrc                Sept.   5,  1991                        *}
  21. {*                        Feature Teller.app                Sept.   5,  1991                        *}
  22. {*                                                                                                       *}
  23. {*        Feature Teller is an example program that demonstrates how to use the Gestalt    *}
  24. {*        Manger to determine the features installed on the Macintosh.  Information            *}
  25. {*        that is returned is:                                                                        *}
  26. {*                                                                                                       *}
  27. {*                        CPU type                                                                    *}
  28. {*                        Processor model                                                            *}
  29. {*                        PMU type                                                                    *}
  30. {*                        Keyboard type                                                            *}
  31. {*                        AppleTalk version                                                        *}
  32. {*                        Amount of memory                                                        *}
  33. {*                        Address mode                                                                *}
  34. {*                        AppleEvents status                                                        *}
  35. {*                        Comm Toolbox version                                                    *}
  36. {*                        Presence of parity memory                                                *}
  37. {*                                                                                                       *}
  38. {*            The program writes the information to the console window which is            *}
  39. {*            presented by the Think Pascal compiler.                                            *}
  40. {*                                                                                                       *}
  41. {*            This program is designed to be a reference on how to handle calls                *}
  42. {*            to the Gestalt manager.  This program is not designed as a reference            *}
  43. {*            for a full blown program that provides a proper user interface.                    *}
  44. {*                                                                                                       *}
  45. {*----------------------------------------------------------------------------- *}
  46.  
  47.  
  48. program FeatureTeller;
  49.  
  50.  
  51.     const
  52.         BASE_RES_ID = 128;                        { beginning resource id for menus }
  53.         ABOUT_ALERT = 128;                        { About box  resource id }
  54.  
  55.         SLEEP = 60;                                    { value used for WaitNextEvent }
  56.         WNE_TRAP_NUM = $60;
  57.         UNIMPL_TRAP_NUM = $9F;
  58.  
  59.         APPLE_MENU_ID = BASE_RES_ID;            { Resource id for the Apple menu }
  60.         ABOUT_ITEM = 1;
  61.  
  62.         FILE_MENU_ID = BASE_RES_ID + 1;        { Resource id for the File menu }
  63.         QUIT_ITEM = 1;
  64.  
  65.         EDIT_MENU_ID = BASE_RES_ID + 2;        { Resource if for the Edit menu }
  66.         CUT_ITEM = 1;
  67.         COPY_ITEM = 2;
  68.         PASTE_ITEM = 3;
  69.         CLEAR_ITEM = 4;
  70.  
  71.         SYS_VERSION = 2;                            { SysEnvirons version information }
  72.         NIL_STRING = ' ';
  73.  
  74.  
  75.     var
  76.         gDone, gWNEImpLemented: BooLean;
  77.         gTheEvent: EventRecord;
  78.  
  79. {-----------------------> END OF DECLARATIONS <-----------------}
  80.  
  81.  
  82. {----------------> CloseSysWindow <---------------------}
  83. {  This routine handles the closing of desk accessory windows }
  84. {-------------------------------------------------------}
  85.     procedure CloseSysWindow;
  86.         var
  87.             whichWindow: WindowPeek;
  88.             accNumber: INTEGER;
  89.  
  90.     begin
  91.         whichWindow := WindowPeek(FrontWindow);
  92.  
  93.         accNumber := whichWindow^.windowKind;
  94.         CloseDeskAcc(accNumber);
  95.     end;
  96.  
  97.  
  98. { *****************   HandleEditChoice  ** ***************}
  99. {*  This routines handles event parsing if the user clicks in the Edit menu  *}
  100. {************************************************}
  101.  
  102.     procedure HandleEditChoice (theItem: INTEGER);
  103.         var
  104.             itemType: INTEGER;
  105.             editMenu: MenuHandle;
  106.  
  107.     begin
  108.         editMenu := GetMHandle(EDIT_MENU_ID);
  109.         case theItem of
  110.             CUT_ITEM: 
  111.                 SysBeep(20);
  112.             COPY_ITEM: 
  113.                 SysBeep(20);
  114.             PASTE_ITEM: 
  115.                 SysBeep(20);
  116.             CLEAR_ITEM: 
  117.                 SysBeep(20);
  118.         end;
  119.     end;
  120.  
  121.  
  122. { *************** HandleFileChoice  *********************}
  123. {*  This routines handles event parsing if the user clicks in the File menu  *}
  124. {************************************************}
  125.  
  126.     procedure HandleFileChoice (theItem: INTEGER);
  127.         var
  128.             itemType: INTEGER;
  129.             fileMenu: MenuHandle;
  130.  
  131.     begin
  132.         fileMenu := GetMHandle(FILE_MENU_ID);
  133.         case theItem of
  134.             QUIT_ITEM: 
  135.                 begin
  136.                     CloseSysWindow;
  137.                     gDone := TRUE;
  138.                 end;
  139.         end;
  140.     end;
  141.  
  142.  
  143.  
  144. { *************** HandleAppleChoice  *********************}
  145. {*  This routines handles event parsing if the user clicks in the Apple menu   *}
  146. {**************************************************}
  147.  
  148.     procedure HandleAppleChoice (theItem: INTEGER);
  149.         var
  150.             accName: Str255;
  151.             accNumber, dummY: INTEGER;
  152.             itemType: INTEGER;
  153.             appleMenu: MenuHandle;
  154.  
  155.     begin
  156.         case theItem of
  157.             ABOUT_ITEM: 
  158.                 dummy := NoteAlert(ABOUT_ALERT, nil);
  159.             otherwise
  160.                 begin
  161.                     appleMenu := GetMHandle(APPLE_MENU_ID);
  162.                     GetItem(appleMenu, theItem, accName);
  163.                     accNumber := OpenDeskAcc(accName);
  164.                 end;
  165.         end;
  166.     end;
  167.  
  168.  
  169.  
  170. { *************** HandleMenuChoice  *********************}
  171. {*  This routines which menu item the user clicks on and then calls the        *}
  172. {*  appropriate routine to handle events in the correct menu.                  *}
  173. {*************************************************}
  174.  
  175.     procedure HandleMenuChoice (menuChoice: LONGINT);
  176.         var
  177.             theMenu, theItem: INTEGER;
  178.  
  179.     begin
  180.         if menuChoice <> 0 then
  181.             begin
  182.                 theMenu := HiWord(menuChoice);
  183.                 theItem := LoWord(menuChoice);
  184.  
  185.                 case theMenu of
  186.                     400: 
  187.                         HandleAppleChoice(theItem);
  188.                     FILE_MENU_ID: 
  189.                         HandleFileChoice(theItem);
  190.                     EDIT_MENU_ID: 
  191.                         HandleEditChoice(theItem);
  192.                 end;
  193.  
  194.                 HiliteMenu(0);
  195.             end;
  196.     end;
  197.  
  198.  
  199.  
  200. { ***************** HandleMouseDown  ***********************}
  201. {*  This routines determines where a user clicks and calls the appropriate routine *}
  202. {*****************************************************}
  203.  
  204.     procedure HandleMouseDown;
  205.         var
  206.             whichWindow: WindowPtr;
  207.             thePart: INTEGER;
  208.             menuChoice, windSize: LONGINT;
  209.  
  210.     begin
  211.         thePart := FindWindow(gTheEvent.where, whichWindow);
  212.         case thePart of
  213.             inMenuBar: 
  214.                 begin
  215.                     menuChoice := MenuSelect(gTheEvent.where);
  216.                     HandleMenuChoice(menuChoice);
  217.                 end;
  218.  
  219.             inSysWindow: 
  220.                 SystemClick(gTheEvent, whichWindow);
  221.  
  222.             inContent: 
  223.                 SysBeep(20);
  224.  
  225.             inDrag: 
  226.                 DragWindow(whichWindow, gTheEvent.where, screenBits.bounds);
  227.  
  228.             inGrow: 
  229.                 SysBeep(20);
  230.  
  231.             inGoAway: 
  232.                 begin
  233.                     if TrackGoAway(whichWindow, gTheEvent.where) then
  234.                         begin
  235.                             if FrontWindow = whichWindow then
  236.                                 DisposeWindow(whichWindow)
  237.                             else
  238.                                 CloseSysWindow;
  239.                         end;
  240.                 end;
  241.  
  242.             InZoomIn: 
  243.                 SysBeep(20);
  244.  
  245.             InZoomOut: 
  246.                 SysBeep(20);
  247.         end;
  248.     end;
  249.  
  250.  
  251.  
  252. { ****************** HandleEvent  *********************}
  253. {*  This routines calls either WaitNextEvent or GetNextEvent depending    *}
  254. {*  on which routine is supported.    This is the main event loop.                *}
  255. {************************************************}
  256.  
  257.     procedure HandleEvent;
  258.         var
  259.             theChar: CHAR;
  260.             dummy: BOOLEAN;
  261.  
  262.     begin
  263.         if gWNEImplemented then
  264.             dummy := WaitNextEvent(everyEvent, gTheEvent, SLEEP, nil)
  265.         else
  266.             begin
  267.                 SystemTask;
  268.                 dummy := GetNextEvent(everyEvent, gTheEvent);
  269.             end;
  270.  
  271.  
  272.         case gTheEvent.what of
  273.             mouseDown: 
  274.                 HandleMouseDown;
  275.             keyDown, autoKey: 
  276.                 begin
  277.                     theChar := CHR(BitAnd(gTheEvent.message, charCodeMask));
  278.                     if (BitAnd(gTheEvent.modifiers, cmdKey) <> 0) then
  279.                         HandleMenuChoice(MenuKey(theChar));
  280.                 end;
  281.         end;
  282.     end;
  283.  
  284.  
  285.  
  286. { ***************** MainLoop  ************************}
  287. {*  This routines repeats until the user selects Quit                             *}
  288. {************************************************}
  289.  
  290.     procedure MainLoop;
  291.     begin
  292.         gDone := FALSE;
  293.         gWNEImplemented := (NGetTrapAddress(WNE_TRAP_NUM, ToolTrap) <> NGetTrapAddress(UNIMPL_TRAP_NUM, ToolTrap));
  294.         while gDone = FALSE do
  295.             HandleEvent;
  296.     end;
  297.  
  298.  
  299.  
  300. { ****************** MenuBarInit  *********************}
  301. {*  This routines draws the Menu Bar which is read in from a Resource file *}
  302. {************************************************}
  303.  
  304.     procedure MenuBarInit;
  305.         var
  306.             myMenuBar: Handle;
  307.             aMenu: MenuHandle;
  308.  
  309.     begin
  310.         myMenuBar := GetNewMBar(BASE_RES_ID);
  311.         SetMenuBar(myMenuBar);
  312.         DisposHandle(myMenuBar);
  313.  
  314.         aMenu := GetMenu(APPLE_MENU_ID);
  315.         AddResMenu(aMenu, 'DRVR');
  316.  
  317.         aMenu := GetMenu(FILE_MENU_ID);
  318.         InsertMenu(aMenu, 0);
  319.  
  320.         aMenu := GetMenu(EDIT_MENU_ID);
  321.         InsertMenu(aMenu, 0);
  322.  
  323.         DrawMenuBar;
  324.     end;
  325.  
  326.  
  327.  
  328. { *************** NumToHexString  *********************}
  329. {*  This routine converts from a number to hexadecimal                         *}
  330. {************************************************}
  331.  
  332.     function NumToHexString (theInt: LONGINT; numBytes: INTEGER): STR255;
  333.         var
  334.             myArray: string[16];
  335.             myString: string[8];
  336.             x: INTEGER;
  337.  
  338.     begin
  339.         myArray := '0123456789ABCDEF';
  340.         myString := myArray[BAND(theInt, $0F) + 1];
  341.         for x := 1 to (numBytes * 2 - 1) do
  342.             begin
  343.                 theInt := BSR(theInt, 4);
  344.                 myString := Concat(myArray[BAND(theInt, $0F) + 1], myString);
  345.             end;
  346.         NumToHexString := MyString;
  347.     end;
  348.  
  349.  
  350.  
  351. { ******************* Gestalt  *********************}
  352. {*  Inline code to call the Gestalt Manager                                      *}
  353. {************************************************}
  354.  
  355.     function Gestalt (code: OSType; var feature: LONGINT): OSErr;
  356.  
  357.     inline
  358.         $225F, {MOVE.L (SP)+,A0}
  359.         $201F, {MOVE.L (SP)+,D0}
  360.         $A1AD, {_Gestalt}
  361.         $2288, {MOVE.L A0, (A1)}
  362.         $3E80; {MOVE.W, D0,(SP)}
  363.  
  364.  
  365.  
  366. { ***************** UseGestalt  *********************}
  367. {*  This routines places all of the Gestalt calls                             *}
  368. {************************************************}
  369.  
  370.     procedure UseGestalt;
  371.         var
  372.             status: OSErr;
  373.             Dummy, theError, x: integer;
  374.             theString, aString: Str255;
  375.             theMachine, theAddress, memory, bytes: LONGINT;
  376.  
  377.     begin
  378.         InitCursor;
  379.         ShowText;
  380.  
  381.         theError := Gestalt('mach', theMachine);
  382.         case theMachine of
  383.             1: 
  384.                 writeln('Macintosh 128K');
  385.             2: 
  386.                 writeln('Macintosh XL');
  387.             3: 
  388.                 writeln('Macintosh 512KE');
  389.             4: 
  390.                 writeln('Macintosh Plus');
  391.             5: 
  392.                 writeln('Macintosh SE');
  393.             6: 
  394.                 writeln('Macintosh II');
  395.             7: 
  396.                 writeln('Macintosh IIx');
  397.             8: 
  398.                 writeln('Machintosh IIcx');
  399.             9: 
  400.                 writeln('Macintosh SE/30');
  401.             10: 
  402.                 writeln('Macintosh Portable');
  403.             11: 
  404.                 writeln('Macintosh IIci');
  405.             13: 
  406.                 writeln('Macintosh IIfx');
  407.             17: 
  408.                 writeln('Macintosh Classic');
  409.             18: 
  410.                 writeln('Macintosh IIsi');
  411.             19: 
  412.                 writeln('Macintosh LC');
  413.             otherwise
  414.                 writeln('Machine type = ', theMachine);
  415.         end;
  416.  
  417.  
  418.         theError := Gestalt('proc', theMachine);
  419.         case theMachine of
  420.             1: 
  421.                 writeln('MC68000 processor');
  422.             2: 
  423.                 writeln('MC68010 processor');
  424.             3: 
  425.                 writeln('MC68020 processor');
  426.             4: 
  427.                 writeln('MC68030 processor');
  428.             5: 
  429.                 writeln('MC68040 processor');
  430.             otherwise
  431.                 writeln('processor = ', theMachine);
  432.         end;
  433.  
  434.  
  435.         theError := Gestalt('fpu ', theMachine);
  436.         case theMachine of
  437.             0: 
  438.                 writeln('No FPU installed');
  439.             1: 
  440.                 writeln('68881 installed');
  441.             2: 
  442.                 writeln('68882 installed');
  443.             otherwise
  444.                 writeln('PMU type = ', theMachine);
  445.         end;
  446.  
  447.  
  448.         theError := Gestalt('kbd ', theMachine);
  449.         case theMachine of
  450.             1: 
  451.                 writeln('Macintosh keyboard');
  452.             2: 
  453.                 writeln('Macintosh keyboard with keypad');
  454.             3: 
  455.                 writeln('Mac Plus keyboard');
  456.             4: 
  457.                 writeln('Macintosh Extended keyboard');
  458.             5: 
  459.                 writeln('Macintosh Standard keyboard');
  460.             6: 
  461.                 writeln('Portable keyboard');
  462.             7: 
  463.                 writeln('Portable ISO keyboard');
  464.             8: 
  465.                 writeln('Standard ISO keyboard');
  466.             9: 
  467.                 writeln('Extended ISO keyboard');
  468.             10: 
  469.                 writeln('ADB keyboard II');
  470.             11: 
  471.                 writeln('ADB ISO keyboard II');
  472.             otherwise
  473.                 writeln('keyboard type = ', theMachine);
  474.         end;
  475.  
  476.         theError := Gestalt('atlk', theMachine);
  477.         NumToString(theMachine, aString);
  478.         if (aString = '0') then
  479.             writeln('AppleTalk not installed')
  480.         else
  481.             writeln('Appletalk version = ', aString);
  482.  
  483.         theError := Gestalt('ram ', theMachine);
  484.         memory := theMachine div 1048576;
  485.         NumToString(memory, aString);
  486.         writeln('Memory = ', aString, ' Megs');
  487.  
  488.         theError := Gestalt('addr', theMachine);
  489.         case theMachine of
  490.             1: 
  491.                 writeln('32 bit addressing enabled');
  492.             2: 
  493.                 writeln('32 bit clean block headers');
  494.             3: 
  495.                 writeln('32 bit capable');
  496.             otherwise
  497.                 begin
  498.                     NumToString(theMachine, aString);
  499.                     writeln('Address mode = ', aString);
  500.                 end;
  501.         end;
  502.  
  503.         theError := gestalt('evnt', theMachine);
  504.         case theMachine of
  505.             0: 
  506.                 writeln('AppleEvents are present');
  507.             otherwise
  508.                 writeln('AppleEvents are not present');
  509.         end;
  510.  
  511.         theError := gestalt('ctbv', theMachine);
  512.         NumToString(theMachine, aString);
  513.         writeln('Comm Toolbox version = ', aString);
  514.  
  515.  
  516.         theError := gestalt('prty', theMachine);
  517.         if (theMachine = 0) then
  518.             writeln('Parity Memory not installed')
  519.         else
  520.             writeln('Parity Memory installed');
  521.     end;
  522.  
  523.  
  524.  
  525. { *************** NumToolboxTraps  *********************}
  526. {*  This routine checks to see what Toolbox traps are available on the mac  *}
  527. {*************************************************}
  528.  
  529.     function NumToolboxTraps: INTEGER;
  530.         const
  531.             _InitGraf = $A86E;
  532.  
  533.     begin
  534.         if NGetTrapAddress(_InitGraf, ToolTrap) = NGetTrapAddress($AA6E, ToolTrap) then
  535.             NumToolboxTraps := $200
  536.         else
  537.             NumToolboxTraps := $400;
  538.     end;
  539.  
  540.  
  541.  
  542. { *************** GetTrapType  ************************}
  543. {*  This routine checks to see what Toolbox traps are available on the mac  *}
  544. {*************************************************}
  545.  
  546.     function GetTrapType (theTrap: INTEGER): TrapType;
  547.         const
  548.             TrapMask = $0800;
  549.  
  550.     begin
  551.         if BAND(theTrap, TrapMask) > 0 then
  552.             GetTrapType := ToolTrap
  553.         else
  554.             GetTrapType := OSTrap;
  555.     end;
  556.  
  557.  
  558. { *************** TrapAvailable  ************************}
  559. {*  This routine checks to see what Toolbox traps are available on the mac  *}
  560. {*************************************************}
  561.  
  562.     function TrapAvailable (theTrap: INteger): boolean;
  563.         const
  564.             _Unimplemented = $9F;
  565.  
  566.         var
  567.             tType: TrapType;
  568.  
  569.     begin
  570.         tType := GetTrapType(theTrap);
  571.         if tType = ToolTrap then
  572.             begin
  573.                 theTrap := BAND(theTrap, $07FF);
  574.                 if theTrap >= NumToolboxTraps then
  575.                     theTrap := _Unimplemented;
  576.             end;
  577.         TrapAvailable := NgetTrapAddress(theTrap, tType) <> NGetTrapAddress(_Unimplemented, ToolTrap);
  578.     end;
  579.  
  580.  
  581. { *************** GestaltAvailable  ************************}
  582. {*  This routine checks to see if Gestalt is supported on the Mac.                  *}
  583. {***************************************************}
  584.  
  585.     function GestaltAvailable: Boolean;
  586.         const
  587.             _Gestalt = $A1AD;
  588.  
  589.     begin
  590.         GestaltAvailable := TrapAvailable(_Gestalt);
  591.     end;
  592.  
  593.  
  594. { ***************** UseSysEnviron  ************************}
  595. {*  This routine places all of the calls to SysEnviron if Gestalt is not supported  *}
  596. {****************************************************}
  597.     procedure UseSysEnviron;
  598.         var
  599.             MPPOpen, status: OSErr;
  600.             SysEnvData: SysEnvRec;
  601.             dummy: INTEGER;
  602.             FPU, CQD: BOOLEAN;
  603.             memory: LONGINT;
  604.             aString: STR255;
  605.             numBytes: INTEGER;
  606.  
  607.     begin
  608.         InitCursor;
  609.         ShowText;
  610.  
  611.         status := SysEnvirons(SYS_VERSION, SysEnvData);
  612.         memory := SysEnvData.systemVersion;
  613.         numBytes := 2;
  614.         astring := NumToHexString(memory, numBytes);
  615.         writeln('System version = ', aString);
  616.         case SysEnvData.machineType of
  617.             0: 
  618.                 writeln('Machine type unknown');
  619.             -1: 
  620.                 writeln('Fat Mac');
  621.             -2: 
  622.                 writeln('MacintoshXL/Lisa');
  623.             1: 
  624.                 writeln('Macintosh 512K enhanced');
  625.             2: 
  626.                 writeln('Macintosh Plus');
  627.             3: 
  628.                 writeln('Macintosh SE');
  629.             4: 
  630.                 writeln('Macintosh II');
  631.             5: 
  632.                 writeln('Macintosh IIx');
  633.             6: 
  634.                 writeln('Macintosh IIcx');
  635.             7: 
  636.                 writeln('Macintosh SE/30');
  637.  
  638.             9: 
  639.                 writeln('Macintosh IIci');
  640.             11: 
  641.                 writeln('Macintosh IIfx');
  642.  
  643.             17: 
  644.                 writeln('Macintosh LC');
  645.             20: 
  646.                 writeln('Machine type = Spike');
  647.             otherwise
  648.                 writeln('Machine type = ', SysEnvData.machineType);
  649.         end;
  650.  
  651.         case SysEnvData.processor of
  652.             0: 
  653.                 writeln('Unrecogonized processor');
  654.             1: 
  655.                 writeln('MC68000 processor');
  656.             2: 
  657.                 writeln('MC68010 processor');
  658.             3: 
  659.                 writeln('MC68020 processor');
  660.             4: 
  661.                 writeln('MC68030 processor');
  662.             5: 
  663.                 writeln('MC68040 processor');
  664.             otherwise
  665.                 writeln('processor = ', SysEnvData.processor);
  666.         end;
  667.  
  668.         if (SysEnvData.hasFPU) then
  669.             writeln('Floating Point processor installed')
  670.         else
  671.             writeln('Floating Point processor not installed');
  672.  
  673.         if (SysEnvData.hasColorQD) then
  674.             writeln('Color QuickDraw installed')
  675.         else
  676.             writeln('Color QuickDraw not installed');
  677.  
  678.         case SysEnvData.keyBoardType of
  679.             0: 
  680.                 writeln('Macintosh Plus keyboard with keypad');
  681.             1: 
  682.                 writeln('Macintosh keyboard');
  683.             2: 
  684.                 writeln(' Macintosh keyboard and keypad');
  685.             3: 
  686.                 writeln('Macintosh plus keyboard');
  687.             4: 
  688.                 writeln('Apple extended keyboard');
  689.             5: 
  690.                 writeln('Standard Apple Desktop bus keyboard');
  691.             10: 
  692.                 writeln('Macintosh LC keyboard');
  693.             otherwise
  694.                 writeln('keyBoardType = ', SysEnvData.keyBoardType);
  695.         end;
  696.  
  697.         dummy := MPPOpen;
  698.         if (dummy = noErr) then
  699.             begin
  700.                 dummy := SysEnvData.atDrvrVersNum;
  701.                 writeln('AppleTalk version = ', dummy);
  702.             end
  703.         else
  704.             writeln('AppleTalk not installed');
  705.     end;
  706.  
  707.  
  708. { *************** Sys6OrLater  ************************}
  709. {*  This routine checks to see if Gestalt or SysEnvirons should be used          *}
  710. {*************************************************}
  711.     procedure Sys60rLater;
  712.     begin
  713.         if GestaltAvailable then
  714.             UseGestalt
  715.         else
  716.             UseSysEnviron;
  717.     end;
  718.  
  719.  
  720. { *************** SysInfo  ***************************}
  721. {*  This is the main routine of the program.                                     *}
  722. {*************************************************}
  723. begin
  724.     Sys60rLater;
  725.     MenuBarInit;
  726.     MainLoop;
  727. end.